package com.zy.Reflect;

//反射机制测试类
import com.zy.Domain.Person;
import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectTest1
{
    @Test
    public void test1()
    {
        //1、获取Person对象的Class类对象
        Class<Person>  personClass= Person.class;
        //2、获取成员变量
        Field[] fields = personClass.getFields();
        //3、遍历Field[]数组
        for(Field i:fields)
            System.out.println(i);
        //打印出了公共数据成员a:public java.lang.String com.zy.Domain.Person.a

        System.out.println("---------------------------");

        //获取指定数据成员
        try
        {
            Field a = personClass.getField("a");
            Person person=new Person();
            //给变量设置值，传递一个Person对象
            a.set(person,"张三");
            Object o = a.get(person);
            System.out.println(o);
            System.out.println(person);
        } catch (NoSuchFieldException e)
        {
            e.printStackTrace();
        } catch (IllegalAccessException e)
        {
            e.printStackTrace();
        }

        System.out.println("---------------------------");

        //不考虑修饰符，获取所有字段
        Field[] declaredFields = personClass.getDeclaredFields();
        for(Field i:declaredFields)
            System.out.println(i);

        try
        {
            //获取指定的属性字段，忽略修饰符
            Field b = personClass.getDeclaredField("b");
            Person person1=new Person();
            //忽略权限，暴力反射
            b.setAccessible(true);
            b.set(person1,"李四");
            System.out.println(person1);
        } catch (NoSuchFieldException e)
        {
            e.printStackTrace();
        } catch (IllegalAccessException e)
        {
            e.printStackTrace();
        }
    }

    @Test
    public void test2()
    {
        //1、获取Class类对象
        Class<Person> personClass = Person.class;
        //2、获取所有的构造方法
        Constructor<?>[] constructors = personClass.getConstructors();
        System.out.println(constructors);
        //3、获取指定的构造方法
        try
        {
            Constructor<Person> constructor = personClass.getConstructor(String.class,String.class);
            //创建对象
            Person person = constructor.newInstance("张三","李四");
            System.out.println(person);
            //Person{a='张三', b='李四', c='null', d='null', name='null', age=null, gender='null', birthday=null}
        } catch (NoSuchMethodException e)
        {
            e.printStackTrace();
        } catch (IllegalAccessException e)
        {
            e.printStackTrace();
        } catch (InstantiationException e)
        {
            e.printStackTrace();
        } catch (InvocationTargetException e)
        {
            e.printStackTrace();
        }
    }

    @Test
    public void test3()
    {
        Class<Person> personClass = Person.class;
        try
        {
            //获取指定方法，传递方法名和参数列表
            Method eat = personClass.getMethod("eat");
            Person person=new Person();
            //执行方法，传递对象和参数
            Object invoke1 = eat.invoke(person);
            System.out.println(invoke1);//打印null
            //根据函数名和参数获取方法并执行
            Method eat1 = personClass.getMethod("eat", String.class);
            Object invoke2 = eat1.invoke(person, "西瓜");
            System.out.println(invoke2);  //打印null
        } catch (NoSuchMethodException e)
        {
            e.printStackTrace();
        } catch (IllegalAccessException e)
        {
            e.printStackTrace();
        } catch (InvocationTargetException e)
        {
            e.printStackTrace();
        }

        //获取所有方法
        Method[] methods = personClass.getMethods();
        for(Method i:methods)
        {
            System.out.println(i);
            String name = i.getName();
            //方法中包括父类Object类的方法
            System.out.println(name);
        }


    }
}
